﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FunnyFunction
{
    public class PushBox
    {
        private const string PEO = "♀";
        private const string BLANK = "  ";
        private const string BOX = "◆";

        public string[,] map;

        string mStr = @"
0 0 1 1 1 0 0 0
0 0 1 x 1 0 0 0
0 0 1 0 1 1 1 1
0 0 1 B B 0 x 1
1 1 1 0 A 1 1 1
1 x 0 B B 1 0 0
1 1 1 1 0 1 0 0
0 0 0 1 x 1 0 0
0 0 0 1 1 1 0 0";
        int wd = 0;
        int lt = 0;
        public void Init(string str = "")
        {
            if (string.IsNullOrEmpty(str)) str = mStr;

            var arr = mStr.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            lt = arr.Length;
            for(int j=0;j<arr.Length;j++)
            {
                var line = arr[j];
                var larr = line.Trim().Split(' ');
                if(map==null)
                {
                    wd = larr.Length;
                    map = new string[larr.Length, arr.Length];
                }
                for (int i = 0; i < larr.Length; i++)
                {
                    map[i, j] = larr[i];
                }
            }

            Draw();

            StartPlay();
        }

        private void StartPlay() 
        {
            while (true)
            {
                var key = Console.ReadKey(true).Key;

                switch (key)
                {
                    case ConsoleKey.UpArrow:
                    case ConsoleKey.DownArrow:
                    case ConsoleKey.LeftArrow:
                    case ConsoleKey.RightArrow:
                        Move(key);
                        break;
                    default:
                        break;
                }
            }
        }
        private int curX;
        private int curY;

        private void Move(ConsoleKey key)
        {
            var nX = curX;
            var nX2 = curX;
            var nY = curY;
            var nY2 = curY;
            switch (key)
            {
                case ConsoleKey.UpArrow:
                    nY -= 1;
                    nY2 -= 2;
                    break;
                case ConsoleKey.DownArrow:
                    nY += 1;
                    nY2 += 2;
                    break;
                case ConsoleKey.LeftArrow:
                    nX -= 1;
                    nX2 -= 2;
                    break;
                case ConsoleKey.RightArrow:
                    nX += 1;
                    nX2 += 2;
                    break;
                default:
                    break;
            }
            var value = map[nX, nY];
            if (value == "0")
            {
                // 目标地是空格，直接移动
                DrawPoint(curX, curY, "0");
                DrawPoint(nX, nY, "A");
                return;
            }

            if (value == "B")
            {
                // 目的地是箱子,检查箱子能否继续移动
                var nValue = map[nX2, nY2];
                if (nValue != "0" && nValue!="x")
                    return;

                DrawPoint(nX2, nY2, "B");
                DrawPoint(curX, curY, "0");
                DrawPoint(nX, nY, "A");
            }
        }

        public void Draw()
        {
            for (int j = 0; j < lt; j++)
            {
                for (int i = 0; i < wd; i++)
                {
                    var v = map[i, j];
                    DrawPoint(i, j, v);
                }
            }
        }

        private void DrawPoint(int i,int j, string v)
        {
            map[i, j] = v;
            Console.SetCursorPosition(i * 2, j);
            Console.ForegroundColor = ConsoleColor.White;
            switch (v)
            {
                case "0":
                    Console.Write("  ");
                    break;
                case "1":
                    Console.Write("■"); //    ☺  ¶
                    break;
                case "B":
                    Console.Write("◆");
                    break;
                case "S":
                    Console.Write("♥");
                    break;
                case "A":
                    curX = i;
                    curY = j;
                    Console.Write("♀");
                    break;
                case "x":
                    Console.Write("★");
                    break;
                default:
                    break;
            }
        }
    }
}
